home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / scripts / kconfig / zconf.y < prev   
Encoding:
Lex Description  |  2008-12-24  |  14.5 KB  |  707 lines

  1. %{
  2. /*
  3.  * Copyright (C) 2002 Roman Zippel <zippel@linux-m68k.org>
  4.  * Released under the terms of the GNU GPL v2.0.
  5.  */
  6.  
  7. #include <ctype.h>
  8. #include <stdarg.h>
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include <stdbool.h>
  13.  
  14. #define LKC_DIRECT_LINK
  15. #include "lkc.h"
  16.  
  17. #include "zconf.hash.c"
  18.  
  19. #define printd(mask, fmt...) if (cdebug & (mask)) printf(fmt)
  20.  
  21. #define PRINTD        0x0001
  22. #define DEBUG_PARSE    0x0002
  23.  
  24. int cdebug = PRINTD;
  25.  
  26. extern int zconflex(void);
  27. static void zconfprint(const char *err, ...);
  28. static void zconf_error(const char *err, ...);
  29. static void zconferror(const char *err);
  30. static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken);
  31.  
  32. struct symbol *symbol_hash[257];
  33.  
  34. static struct menu *current_menu, *current_entry;
  35.  
  36. #define YYDEBUG 0
  37. #if YYDEBUG
  38. #define YYERROR_VERBOSE
  39. #endif
  40. %}
  41. %expect 26
  42.  
  43. %union
  44. {
  45.     char *string;
  46.     struct file *file;
  47.     struct symbol *symbol;
  48.     struct expr *expr;
  49.     struct menu *menu;
  50.     struct kconf_id *id;
  51. }
  52.  
  53. %token <id>T_MAINMENU
  54. %token <id>T_MENU
  55. %token <id>T_ENDMENU
  56. %token <id>T_SOURCE
  57. %token <id>T_CHOICE
  58. %token <id>T_ENDCHOICE
  59. %token <id>T_COMMENT
  60. %token <id>T_CONFIG
  61. %token <id>T_MENUCONFIG
  62. %token <id>T_HELP
  63. %token <string> T_HELPTEXT
  64. %token <id>T_IF
  65. %token <id>T_ENDIF
  66. %token <id>T_DEPENDS
  67. %token <id>T_OPTIONAL
  68. %token <id>T_PROMPT
  69. %token <id>T_TYPE
  70. %token <id>T_DEFAULT
  71. %token <id>T_SELECT
  72. %token <id>T_RANGE
  73. %token <id>T_OPTION
  74. %token <id>T_ON
  75. %token <string> T_WORD
  76. %token <string> T_WORD_QUOTE
  77. %token T_UNEQUAL
  78. %token T_CLOSE_PAREN
  79. %token T_OPEN_PAREN
  80. %token T_EOL
  81.  
  82. %left T_OR
  83. %left T_AND
  84. %left T_EQUAL T_UNEQUAL
  85. %nonassoc T_NOT
  86.  
  87. %type <string> prompt
  88. %type <symbol> symbol
  89. %type <expr> expr
  90. %type <expr> if_expr
  91. %type <id> end
  92. %type <id> option_name
  93. %type <menu> if_entry menu_entry choice_entry
  94. %type <string> symbol_option_arg word_opt
  95.  
  96. %destructor {
  97.     fprintf(stderr, "%s:%d: missing end statement for this entry\n",
  98.         $$->file->name, $$->lineno);
  99.     if (current_menu == $$)
  100.         menu_end_menu();
  101. } if_entry menu_entry choice_entry
  102.  
  103. %%
  104. input: stmt_list;
  105.  
  106. stmt_list:
  107.       /* empty */
  108.     | stmt_list common_stmt
  109.     | stmt_list choice_stmt
  110.     | stmt_list menu_stmt
  111.     | stmt_list T_MAINMENU prompt nl
  112.     | stmt_list end            { zconf_error("unexpected end statement"); }
  113.     | stmt_list T_WORD error T_EOL    { zconf_error("unknown statement \"%s\"", $2); }
  114.     | stmt_list option_name error T_EOL
  115. {
  116.     zconf_error("unexpected option \"%s\"", kconf_id_strings + $2->name);
  117. }
  118.     | stmt_list error T_EOL        { zconf_error("invalid statement"); }
  119. ;
  120.  
  121. option_name:
  122.     T_DEPENDS | T_PROMPT | T_TYPE | T_SELECT | T_OPTIONAL | T_RANGE | T_DEFAULT
  123. ;
  124.  
  125. common_stmt:
  126.       T_EOL
  127.     | if_stmt
  128.     | comment_stmt
  129.     | config_stmt
  130.     | menuconfig_stmt
  131.     | source_stmt
  132. ;
  133.  
  134. option_error:
  135.       T_WORD error T_EOL        { zconf_error("unknown option \"%s\"", $1); }
  136.     | error T_EOL            { zconf_error("invalid option"); }
  137. ;
  138.  
  139.  
  140. /* config/menuconfig entry */
  141.  
  142. config_entry_start: T_CONFIG T_WORD T_EOL
  143. {
  144.     struct symbol *sym = sym_lookup($2, 0);
  145.     sym->flags |= SYMBOL_OPTIONAL;
  146.     menu_add_entry(sym);
  147.     printd(DEBUG_PARSE, "%s:%d:config %s\n", zconf_curname(), zconf_lineno(), $2);
  148. };
  149.  
  150. config_stmt: config_entry_start config_option_list
  151. {
  152.     menu_end_entry();
  153.     printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
  154. };
  155.  
  156. menuconfig_entry_start: T_MENUCONFIG T_WORD T_EOL
  157. {
  158.     struct symbol *sym = sym_lookup($2, 0);
  159.     sym->flags |= SYMBOL_OPTIONAL;
  160.     menu_add_entry(sym);
  161.     printd(DEBUG_PARSE, "%s:%d:menuconfig %s\n", zconf_curname(), zconf_lineno(), $2);
  162. };
  163.  
  164. menuconfig_stmt: menuconfig_entry_start config_option_list
  165. {
  166.     if (current_entry->prompt)
  167.         current_entry->prompt->type = P_MENU;
  168.     else
  169.         zconfprint("warning: menuconfig statement without prompt");
  170.     menu_end_entry();
  171.     printd(DEBUG_PARSE, "%s:%d:endconfig\n", zconf_curname(), zconf_lineno());
  172. };
  173.  
  174. config_option_list:
  175.       /* empty */
  176.     | config_option_list config_option
  177.     | config_option_list symbol_option
  178.     | config_option_list depends
  179.     | config_option_list help
  180.     | config_option_list option_error
  181.     | config_option_list T_EOL
  182. ;
  183.  
  184. config_option: T_TYPE prompt_stmt_opt T_EOL
  185. {
  186.     menu_set_type($1->stype);
  187.     printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
  188.         zconf_curname(), zconf_lineno(),
  189.         $1->stype);
  190. };
  191.  
  192. config_option: T_PROMPT prompt if_expr T_EOL
  193. {
  194.     menu_add_prompt(P_PROMPT, $2, $3);
  195.     printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
  196. };
  197.  
  198. config_option: T_DEFAULT expr if_expr T_EOL
  199. {
  200.     menu_add_expr(P_DEFAULT, $2, $3);
  201.     if ($1->stype != S_UNKNOWN)
  202.         menu_set_type($1->stype);
  203.     printd(DEBUG_PARSE, "%s:%d:default(%u)\n",
  204.         zconf_curname(), zconf_lineno(),
  205.         $1->stype);
  206. };
  207.  
  208. config_option: T_SELECT T_WORD if_expr T_EOL
  209. {
  210.     menu_add_symbol(P_SELECT, sym_lookup($2, 0), $3);
  211.     printd(DEBUG_PARSE, "%s:%d:select\n", zconf_curname(), zconf_lineno());
  212. };
  213.  
  214. config_option: T_RANGE symbol symbol if_expr T_EOL
  215. {
  216.     menu_add_expr(P_RANGE, expr_alloc_comp(E_RANGE,$2, $3), $4);
  217.     printd(DEBUG_PARSE, "%s:%d:range\n", zconf_curname(), zconf_lineno());
  218. };
  219.  
  220. symbol_option: T_OPTION symbol_option_list T_EOL
  221. ;
  222.  
  223. symbol_option_list:
  224.       /* empty */
  225.     | symbol_option_list T_WORD symbol_option_arg
  226. {
  227.     struct kconf_id *id = kconf_id_lookup($2, strlen($2));
  228.     if (id && id->flags & TF_OPTION)
  229.         menu_add_option(id->token, $3);
  230.     else
  231.         zconfprint("warning: ignoring unknown option %s", $2);
  232.     free($2);
  233. };
  234.  
  235. symbol_option_arg:
  236.       /* empty */        { $$ = NULL; }
  237.     | T_EQUAL prompt    { $$ = $2; }
  238. ;
  239.  
  240. /* choice entry */
  241.  
  242. choice: T_CHOICE word_opt T_EOL
  243. {
  244.     struct symbol *sym = sym_lookup($2, SYMBOL_CHOICE);
  245.     sym->flags |= SYMBOL_AUTO;
  246.     menu_add_entry(sym);
  247.     menu_add_expr(P_CHOICE, NULL, NULL);
  248.     printd(DEBUG_PARSE, "%s:%d:choice\n", zconf_curname(), zconf_lineno());
  249. };
  250.  
  251. choice_entry: choice choice_option_list
  252. {
  253.     $$ = menu_add_menu();
  254. };
  255.  
  256. choice_end: end
  257. {
  258.     if (zconf_endtoken($1, T_CHOICE, T_ENDCHOICE)) {
  259.         menu_end_menu();
  260.         printd(DEBUG_PARSE, "%s:%d:endchoice\n", zconf_curname(), zconf_lineno());
  261.     }
  262. };
  263.  
  264. choice_stmt: choice_entry choice_block choice_end
  265. ;
  266.  
  267. choice_option_list:
  268.       /* empty */
  269.     | choice_option_list choice_option
  270.     | choice_option_list depends
  271.     | choice_option_list help
  272.     | choice_option_list T_EOL
  273.     | choice_option_list option_error
  274. ;
  275.  
  276. choice_option: T_PROMPT prompt if_expr T_EOL
  277. {
  278.     menu_add_prompt(P_PROMPT, $2, $3);
  279.     printd(DEBUG_PARSE, "%s:%d:prompt\n", zconf_curname(), zconf_lineno());
  280. };
  281.  
  282. choice_option: T_TYPE prompt_stmt_opt T_EOL
  283. {
  284.     if ($1->stype == S_BOOLEAN || $1->stype == S_TRISTATE) {
  285.         menu_set_type($1->stype);
  286.         printd(DEBUG_PARSE, "%s:%d:type(%u)\n",
  287.             zconf_curname(), zconf_lineno(),
  288.             $1->stype);
  289.     } else
  290.         YYERROR;
  291. };
  292.  
  293. choice_option: T_OPTIONAL T_EOL
  294. {
  295.     current_entry->sym->flags |= SYMBOL_OPTIONAL;
  296.     printd(DEBUG_PARSE, "%s:%d:optional\n", zconf_curname(), zconf_lineno());
  297. };
  298.  
  299. choice_option: T_DEFAULT T_WORD if_expr T_EOL
  300. {
  301.     if ($1->stype == S_UNKNOWN) {
  302.         menu_add_symbol(P_DEFAULT, sym_lookup($2, 0), $3);
  303.         printd(DEBUG_PARSE, "%s:%d:default\n",
  304.             zconf_curname(), zconf_lineno());
  305.     } else
  306.         YYERROR;
  307. };
  308.  
  309. choice_block:
  310.       /* empty */
  311.     | choice_block common_stmt
  312. ;
  313.  
  314. /* if entry */
  315.  
  316. if_entry: T_IF expr nl
  317. {
  318.     printd(DEBUG_PARSE, "%s:%d:if\n", zconf_curname(), zconf_lineno());
  319.     menu_add_entry(NULL);
  320.     menu_add_dep($2);
  321.     $$ = menu_add_menu();
  322. };
  323.  
  324. if_end: end
  325. {
  326.     if (zconf_endtoken($1, T_IF, T_ENDIF)) {
  327.         menu_end_menu();
  328.         printd(DEBUG_PARSE, "%s:%d:endif\n", zconf_curname(), zconf_lineno());
  329.     }
  330. };
  331.  
  332. if_stmt: if_entry if_block if_end
  333. ;
  334.  
  335. if_block:
  336.       /* empty */
  337.     | if_block common_stmt
  338.     | if_block menu_stmt
  339.     | if_block choice_stmt
  340. ;
  341.  
  342. /* menu entry */
  343.  
  344. menu: T_MENU prompt T_EOL
  345. {
  346.     menu_add_entry(NULL);
  347.     menu_add_prompt(P_MENU, $2, NULL);
  348.     printd(DEBUG_PARSE, "%s:%d:menu\n", zconf_curname(), zconf_lineno());
  349. };
  350.  
  351. menu_entry: menu depends_list
  352. {
  353.     $$ = menu_add_menu();
  354. };
  355.  
  356. menu_end: end
  357. {
  358.     if (zconf_endtoken($1, T_MENU, T_ENDMENU)) {
  359.         menu_end_menu();
  360.         printd(DEBUG_PARSE, "%s:%d:endmenu\n", zconf_curname(), zconf_lineno());
  361.     }
  362. };
  363.  
  364. menu_stmt: menu_entry menu_block menu_end
  365. ;
  366.  
  367. menu_block:
  368.       /* empty */
  369.     | menu_block common_stmt
  370.     | menu_block menu_stmt
  371.     | menu_block choice_stmt
  372. ;
  373.  
  374. source_stmt: T_SOURCE prompt T_EOL
  375. {
  376.     printd(DEBUG_PARSE, "%s:%d:source %s\n", zconf_curname(), zconf_lineno(), $2);
  377.     zconf_nextfile($2);
  378. };
  379.  
  380. /* comment entry */
  381.  
  382. comment: T_COMMENT prompt T_EOL
  383. {
  384.     menu_add_entry(NULL);
  385.     menu_add_prompt(P_COMMENT, $2, NULL);
  386.     printd(DEBUG_PARSE, "%s:%d:comment\n", zconf_curname(), zconf_lineno());
  387. };
  388.  
  389. comment_stmt: comment depends_list
  390. {
  391.     menu_end_entry();
  392. };
  393.  
  394. /* help option */
  395.  
  396. help_start: T_HELP T_EOL
  397. {
  398.     printd(DEBUG_PARSE, "%s:%d:help\n", zconf_curname(), zconf_lineno());
  399.     zconf_starthelp();
  400. };
  401.  
  402. help: help_start T_HELPTEXT
  403. {
  404.     current_entry->help = $2;
  405. };
  406.  
  407. /* depends option */
  408.  
  409. depends_list:
  410.       /* empty */
  411.     | depends_list depends
  412.     | depends_list T_EOL
  413.     | depends_list option_error
  414. ;
  415.  
  416. depends: T_DEPENDS T_ON expr T_EOL
  417. {
  418.     menu_add_dep($3);
  419.     printd(DEBUG_PARSE, "%s:%d:depends on\n", zconf_curname(), zconf_lineno());
  420. };
  421.  
  422. /* prompt statement */
  423.  
  424. prompt_stmt_opt:
  425.       /* empty */
  426.     | prompt if_expr
  427. {
  428.     menu_add_prompt(P_PROMPT, $1, $2);
  429. };
  430.  
  431. prompt:      T_WORD
  432.     | T_WORD_QUOTE
  433. ;
  434.  
  435. end:      T_ENDMENU T_EOL    { $$ = $1; }
  436.     | T_ENDCHOICE T_EOL    { $$ = $1; }
  437.     | T_ENDIF T_EOL        { $$ = $1; }
  438. ;
  439.  
  440. nl:
  441.       T_EOL
  442.     | nl T_EOL
  443. ;
  444.  
  445. if_expr:  /* empty */            { $$ = NULL; }
  446.     | T_IF expr            { $$ = $2; }
  447. ;
  448.  
  449. expr:      symbol                { $$ = expr_alloc_symbol($1); }
  450.     | symbol T_EQUAL symbol            { $$ = expr_alloc_comp(E_EQUAL, $1, $3); }
  451.     | symbol T_UNEQUAL symbol        { $$ = expr_alloc_comp(E_UNEQUAL, $1, $3); }
  452.     | T_OPEN_PAREN expr T_CLOSE_PAREN    { $$ = $2; }
  453.     | T_NOT expr                { $$ = expr_alloc_one(E_NOT, $2); }
  454.     | expr T_OR expr            { $$ = expr_alloc_two(E_OR, $1, $3); }
  455.     | expr T_AND expr            { $$ = expr_alloc_two(E_AND, $1, $3); }
  456. ;
  457.  
  458. symbol:      T_WORD    { $$ = sym_lookup($1, 0); free($1); }
  459.     | T_WORD_QUOTE    { $$ = sym_lookup($1, SYMBOL_CONST); free($1); }
  460. ;
  461.  
  462. word_opt: /* empty */            { $$ = NULL; }
  463.     | T_WORD
  464.  
  465. %%
  466.  
  467. void conf_parse(const char *name)
  468. {
  469.     struct symbol *sym;
  470.     int i;
  471.  
  472.     zconf_initscan(name);
  473.  
  474.     sym_init();
  475.     menu_init();
  476.     modules_sym = sym_lookup(NULL, 0);
  477.     modules_sym->type = S_BOOLEAN;
  478.     modules_sym->flags |= SYMBOL_AUTO;
  479.     rootmenu.prompt = menu_add_prompt(P_MENU, "Linux Kernel Configuration", NULL);
  480.  
  481. #if YYDEBUG
  482.     if (getenv("ZCONF_DEBUG"))
  483.         zconfdebug = 1;
  484. #endif
  485.     zconfparse();
  486.     if (zconfnerrs)
  487.         exit(1);
  488.     if (!modules_sym->prop) {
  489.         struct property *prop;
  490.  
  491.         prop = prop_alloc(P_DEFAULT, modules_sym);
  492.         prop->expr = expr_alloc_symbol(sym_lookup("MODULES", 0));
  493.     }
  494.     menu_finalize(&rootmenu);
  495.     for_all_symbols(i, sym) {
  496.         if (sym_check_deps(sym))
  497.             zconfnerrs++;
  498.         }
  499.     if (zconfnerrs)
  500.         exit(1);
  501.     sym_set_change_count(1);
  502. }
  503.  
  504. const char *zconf_tokenname(int token)
  505. {
  506.     switch (token) {
  507.     case T_MENU:        return "menu";
  508.     case T_ENDMENU:        return "endmenu";
  509.     case T_CHOICE:        return "choice";
  510.     case T_ENDCHOICE:    return "endchoice";
  511.     case T_IF:        return "if";
  512.     case T_ENDIF:        return "endif";
  513.     case T_DEPENDS:        return "depends";
  514.     }
  515.     return "<token>";
  516. }
  517.  
  518. static bool zconf_endtoken(struct kconf_id *id, int starttoken, int endtoken)
  519. {
  520.     if (id->token != endtoken) {
  521.         zconf_error("unexpected '%s' within %s block",
  522.             kconf_id_strings + id->name, zconf_tokenname(starttoken));
  523.         zconfnerrs++;
  524.         return false;
  525.     }
  526.     if (current_menu->file != current_file) {
  527.         zconf_error("'%s' in different file than '%s'",
  528.             kconf_id_strings + id->name, zconf_tokenname(starttoken));
  529.         fprintf(stderr, "%s:%d: location of the '%s'\n",
  530.             current_menu->file->name, current_menu->lineno,
  531.             zconf_tokenname(starttoken));
  532.         zconfnerrs++;
  533.         return false;
  534.     }
  535.     return true;
  536. }
  537.  
  538. static void zconfprint(const char *err, ...)
  539. {
  540.     va_list ap;
  541.  
  542.     fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
  543.     va_start(ap, err);
  544.     vfprintf(stderr, err, ap);
  545.     va_end(ap);
  546.     fprintf(stderr, "\n");
  547. }
  548.  
  549. static void zconf_error(const char *err, ...)
  550. {
  551.     va_list ap;
  552.  
  553.     zconfnerrs++;
  554.     fprintf(stderr, "%s:%d: ", zconf_curname(), zconf_lineno());
  555.     va_start(ap, err);
  556.     vfprintf(stderr, err, ap);
  557.     va_end(ap);
  558.     fprintf(stderr, "\n");
  559. }
  560.  
  561. static void zconferror(const char *err)
  562. {
  563. #if YYDEBUG
  564.     fprintf(stderr, "%s:%d: %s\n", zconf_curname(), zconf_lineno() + 1, err);
  565. #endif
  566. }
  567.  
  568. void print_quoted_string(FILE *out, const char *str)
  569. {
  570.     const char *p;
  571.     int len;
  572.  
  573.     putc('"', out);
  574.     while ((p = strchr(str, '"'))) {
  575.         len = p - str;
  576.         if (len)
  577.             fprintf(out, "%.*s", len, str);
  578.         fputs("\\\"", out);
  579.         str = p + 1;
  580.     }
  581.     fputs(str, out);
  582.     putc('"', out);
  583. }
  584.  
  585. void print_symbol(FILE *out, struct menu *menu)
  586. {
  587.     struct symbol *sym = menu->sym;
  588.     struct property *prop;
  589.  
  590.     if (sym_is_choice(sym))
  591.         fprintf(out, "choice\n");
  592.     else
  593.         fprintf(out, "config %s\n", sym->name);
  594.     switch (sym->type) {
  595.     case S_BOOLEAN:
  596.         fputs("  boolean\n", out);
  597.         break;
  598.     case S_TRISTATE:
  599.         fputs("  tristate\n", out);
  600.         break;
  601.     case S_STRING:
  602.         fputs("  string\n", out);
  603.         break;
  604.     case S_INT:
  605.         fputs("  integer\n", out);
  606.         break;
  607.     case S_HEX:
  608.         fputs("  hex\n", out);
  609.         break;
  610.     default:
  611.         fputs("  ???\n", out);
  612.         break;
  613.     }
  614.     for (prop = sym->prop; prop; prop = prop->next) {
  615.         if (prop->menu != menu)
  616.             continue;
  617.         switch (prop->type) {
  618.         case P_PROMPT:
  619.             fputs("  prompt ", out);
  620.             print_quoted_string(out, prop->text);
  621.             if (!expr_is_yes(prop->visible.expr)) {
  622.                 fputs(" if ", out);
  623.                 expr_fprint(prop->visible.expr, out);
  624.             }
  625.             fputc('\n', out);
  626.             break;
  627.         case P_DEFAULT:
  628.             fputs( "  default ", out);
  629.             expr_fprint(prop->expr, out);
  630.             if (!expr_is_yes(prop->visible.expr)) {
  631.                 fputs(" if ", out);
  632.                 expr_fprint(prop->visible.expr, out);
  633.             }
  634.             fputc('\n', out);
  635.             break;
  636.         case P_CHOICE:
  637.             fputs("  #choice value\n", out);
  638.             break;
  639.         default:
  640.             fprintf(out, "  unknown prop %d!\n", prop->type);
  641.             break;
  642.         }
  643.     }
  644.     if (menu->help) {
  645.         int len = strlen(menu->help);
  646.         while (menu->help[--len] == '\n')
  647.             menu->help[len] = 0;
  648.         fprintf(out, "  help\n%s\n", menu->help);
  649.     }
  650.     fputc('\n', out);
  651. }
  652.  
  653. void zconfdump(FILE *out)
  654. {
  655.     struct property *prop;
  656.     struct symbol *sym;
  657.     struct menu *menu;
  658.  
  659.     menu = rootmenu.list;
  660.     while (menu) {
  661.         if ((sym = menu->sym))
  662.             print_symbol(out, menu);
  663.         else if ((prop = menu->prompt)) {
  664.             switch (prop->type) {
  665.             case P_COMMENT:
  666.                 fputs("\ncomment ", out);
  667.                 print_quoted_string(out, prop->text);
  668.                 fputs("\n", out);
  669.                 break;
  670.             case P_MENU:
  671.                 fputs("\nmenu ", out);
  672.                 print_quoted_string(out, prop->text);
  673.                 fputs("\n", out);
  674.                 break;
  675.             default:
  676.                 ;
  677.             }
  678.             if (!expr_is_yes(prop->visible.expr)) {
  679.                 fputs("  depends ", out);
  680.                 expr_fprint(prop->visible.expr, out);
  681.                 fputc('\n', out);
  682.             }
  683.             fputs("\n", out);
  684.         }
  685.  
  686.         if (menu->list)
  687.             menu = menu->list;
  688.         else if (menu->next)
  689.             menu = menu->next;
  690.         else while ((menu = menu->parent)) {
  691.             if (menu->prompt && menu->prompt->type == P_MENU)
  692.                 fputs("\nendmenu\n", out);
  693.             if (menu->next) {
  694.                 menu = menu->next;
  695.                 break;
  696.             }
  697.         }
  698.     }
  699. }
  700.  
  701. #include "lex.zconf.c"
  702. #include "util.c"
  703. #include "confdata.c"
  704. #include "expr.c"
  705. #include "symbol.c"
  706. #include "menu.c"
  707.